package com.bingo.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bingo.common.R;
import com.bingo.dao.DivideMapper;
import com.bingo.entity.*;
import com.bingo.entity.dto.HappenedInPeriod;
import com.bingo.entity.dto.Transfer;
import com.bingo.entity.dto.everyDayForm.EveryDayDivide;
import com.bingo.entity.dto.intermediary.SiteDivide;
import com.bingo.entity.dto.resp.*;
import com.bingo.entity.dto.todayForm.TodayDivide;
import com.bingo.service.*;
import com.bingo.until.HostHolder;
import com.bingo.until.IsToday;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

@Service
public class DivideServiceImpl extends ServiceImpl<DivideMapper, Divide> implements DivideService {

    private CurPoolService curPoolService;

    @Autowired
    public void setPrePoolService(CurPoolService curPoolService) {
        this.curPoolService = curPoolService;
    }

    private HostHolder hostHolder;
    @Autowired
    public void setHostHolder(HostHolder hostHolder) {
        this.hostHolder = hostHolder;
    }

    private HisPoolService hisPoolService;

    @Autowired
    public void setPoolService(HisPoolService hisPoolService) {
        this.hisPoolService = hisPoolService;
    }

    private SiteService siteService;

    @Autowired
    public void setSiteService(SiteService siteService) {
        this.siteService = siteService;
    }

    private UserService userService;

    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    @Override
    public R add(String poolNoOut, String poolNoIn, Integer quantity, Double weight, Date date, String userId) {

        userId = hostHolder.getUser().getUserId();

        //查询对应塘
        CurPool outPool = curPoolService.getCurPoolByNo(poolNoOut);
        CurPool inPool = curPoolService.getCurPoolByNo(poolNoIn);
        if (outPool == null || inPool == null) {
            return R.error("分入或分出塘不存在!");
        }
        if (outPool.getType()==0){
            return R.error("分出塘是空塘！");
        }

        //查询是否存在当前记录
        QueryWrapper<Divide> wrapper = new QueryWrapper<>();
        wrapper.eq("pool_no", poolNoOut);
        wrapper.eq("date", date);
        wrapper.eq("come_from", poolNoIn);
        wrapper.eq("divide_type", 1);
        Divide out = this.getOne(wrapper);
        //查询分入记录
        QueryWrapper<Divide> wrapper1 = new QueryWrapper<>();
        wrapper1.eq("pool_no", poolNoIn);
        wrapper1.eq("date", date);
        wrapper1.eq("come_from", poolNoOut);
        wrapper1.eq("divide_type", 0);
        Divide in = this.getOne(wrapper1);

        //记录分出记录
        Divide divide = new Divide();
        divide.setDate(date);
        divide.setUserId(userId);
        divide.setReportDate(new Date(System.currentTimeMillis()));
        divide.setDivideType(1);
        divide.setPoolNo(poolNoOut);
        divide.setQuantity(quantity);
        divide.setWeight(weight);
        divide.setComeFrom(poolNoIn);
        divide.setType(outPool.getType());


        //如果不存在该记录
        if (out==null || in==null) {

            this.save(divide);
            //记录分入记录
            divide.setId(divide.getId() + 1);
            divide.setPoolNo(inPool.getPoolNo());
            divide.setComeFrom(outPool.getPoolNo());
            divide.setDivideType(0);
            this.save(divide);


            //修改分入分出塘当前状态
            outPool.setQuantity(outPool.getQuantity() - quantity);
            outPool.setWeight(outPool.getWeight() - weight);
            curPoolService.updateById(outPool);
            inPool.setQuantity(inPool.getQuantity() + quantity);
            inPool.setWeight(inPool.getWeight() + weight);
            //如果原本塘为空塘，鳗鱼类型与分出塘一致
            if (inPool.getType()==0){
                inPool.setType(outPool.getType());
            }
            curPoolService.updateById(inPool);

            //如果不是当天
            if (!IsToday.isToday(date)) {
                QueryWrapper<HisPool> w = new QueryWrapper<>();
                w.eq("pool_no", poolNoOut);
                w.between("date", date, new Date(System.currentTimeMillis()));
                List<HisPool> list = hisPoolService.list(w);
                for (HisPool hisPool : list) {
                    hisPool.setQuantity(hisPool.getQuantity() - quantity);
                    hisPool.setWeight(hisPool.getWeight() - weight);
                    hisPoolService.updateById(hisPool);
                }
                QueryWrapper<HisPool> w1 = new QueryWrapper<>();
                w1.eq("pool_no", poolNoIn);
                w1.between("date", date, new Date(System.currentTimeMillis()));
                List<HisPool> list1 = hisPoolService.list(w1);
                for (HisPool hisPool : list1) {
                    hisPool.setQuantity(hisPool.getQuantity() + quantity);
                    hisPool.setWeight(hisPool.getWeight() + weight);
                    hisPoolService.updateById(hisPool);
                }
            }
            R<String> r = R.success("新增分塘记录成功");
            r.setStatusText("新增分塘记录成功");
            return r;
        }
        else {
            //计算差值
            int quantityDiff = quantity - out.getQuantity();
            double weightDiff = weight - out.getWeight();
            //修改分出记录
            out.setQuantity(quantity);
            out.setWeight(weight);
            out.setUserId(userId);
            this.updateById(out);
            //修改分入记录
            in.setQuantity(quantity);
            in.setWeight(weight);
            in.setUserId(userId);
            this.updateById(in);

            //修改分入分出塘当前状态
            outPool.setQuantity(outPool.getQuantity() - quantityDiff);
            outPool.setWeight(outPool.getWeight() - weightDiff);
            curPoolService.updateById(outPool);
            inPool.setQuantity(inPool.getQuantity() + quantityDiff);
            inPool.setWeight(inPool.getWeight() + weightDiff);
            curPoolService.updateById(inPool);

            //如果不是当天
            if (!IsToday.isToday(date)) {
                QueryWrapper<HisPool> w = new QueryWrapper<>();
                w.eq("pool_no", poolNoOut);
                w.between("date", date, new Date(System.currentTimeMillis()));
                List<HisPool> list = hisPoolService.list(w);
                for (HisPool hisPool : list) {
                    hisPool.setQuantity(hisPool.getQuantity() - quantityDiff);
                    hisPool.setWeight(hisPool.getWeight() - weightDiff);
                    hisPoolService.updateById(hisPool);
                }
                QueryWrapper<HisPool> w1 = new QueryWrapper<>();
                w1.eq("pool_no", poolNoIn);
                w1.between("date", date, new Date(System.currentTimeMillis()));
                List<HisPool> list1 = hisPoolService.list(w1);
                for (HisPool hisPool : list1) {
                    hisPool.setQuantity(hisPool.getQuantity() + quantityDiff);
                    hisPool.setWeight(hisPool.getWeight() + weightDiff);
                    hisPoolService.updateById(hisPool);
                }
            }
            R<String> r = R.success("修改分塘记录成功");
            return r;
        }

    }

    @Override
    public void summaryDivide(String poolNo, Date startDate, Date endDate, HappenedInPeriod happenedInPeriod) {
        Transfer transfer = new Transfer();
        transfer.setAmount(0);
        transfer.setWeight(0.0);
        transfer.setComeFrom("");

        //分进
        QueryWrapper<Divide> inWrapper = new QueryWrapper<>();
        inWrapper.eq("pool_no", poolNo);
        inWrapper.between("date", startDate, endDate);
        inWrapper.eq("divide_type", 0);
        List<Divide> inList = this.list(inWrapper);
        for (Divide divide : inList) {
            transfer.setAmount(transfer.getAmount() + divide.getQuantity());
            transfer.setWeight(transfer.getWeight() + divide.getWeight());
            transfer.setComeFrom(transfer.getComeFrom() + divide.getComeFrom() + " ");
        }

        //分出
        QueryWrapper<Divide> outWrapper = new QueryWrapper<>();
        outWrapper.eq("pool_no", poolNo);
        outWrapper.between("date", startDate, endDate);
        outWrapper.eq("divide_type", 1);
        List<Divide> outList = this.list(outWrapper);
        for (Divide divide : outList) {
            transfer.setAmount(transfer.getAmount() - divide.getQuantity());
            transfer.setWeight(transfer.getWeight() - divide.getWeight());
            transfer.setComeFrom(transfer.getComeFrom() + divide.getComeFrom() + " ");
        }

        if (transfer.getAmount() > 0) {
            transfer.setOutOrIn("分进");
        } else {
            transfer.setOutOrIn("分出");
        }

        happenedInPeriod.setTransfer(transfer);
    }

    @Override
    public List<EveryDayDivide> selectEveryDayDivide(List<String> poolNos, Date startDate, Date endDate) {

        if (poolNos == null || poolNos.size() == 0) {
            poolNos = curPoolService.getPoolNos();
        }

        LinkedList<EveryDayDivide> list = new LinkedList<>();
        for (String poolNo : poolNos) {
            CurPool pool = curPoolService.getCurPoolByNo(poolNo);
            //基础信息
            EveryDayDivide everyDayDivide = new EveryDayDivide();
            everyDayDivide.setPoolNo(poolNo);
            everyDayDivide.setArea(pool.getArea());
            everyDayDivide.setKey(pool.getPoolNo());
            everyDayDivide.setTotalQuantity(0);
            everyDayDivide.setTotalWeight(0.0);
            //每日数据
            QueryWrapper<Divide> wrapper = new QueryWrapper<>();
            wrapper.eq("pool_no", poolNo);
            wrapper.between("date", startDate, endDate);
            List<Divide> divideList = this.list(wrapper);
            //LinkedList<TodayDivide> todayDivides = new LinkedList<>();
            HashMap<String, TodayDivide> hashMap = new HashMap<>();
            for (Divide divide : divideList) {
                TodayDivide todayDivide = new TodayDivide();
                todayDivide.setPoolNo(divide.getPoolNo());
                todayDivide.setDivideType(divide.getDivideType());
                if (divide.getDivideType() == 1) {
                    todayDivide.setQuantity(-divide.getQuantity());
                    todayDivide.setWeight(-divide.getWeight());
                } else {
                    todayDivide.setQuantity(divide.getQuantity());
                    todayDivide.setWeight(divide.getWeight());
                }
                todayDivide.setType(divide.getType());
                todayDivide.setDate(divide.getDate());

                if (hashMap.containsKey(divide.getDate().toString())) {
                    TodayDivide todayDivide1 = hashMap.get(divide.getDate().toString());
                    todayDivide1.setQuantity(todayDivide1.getQuantity() + divide.getQuantity());
                    todayDivide1.setWeight(todayDivide1.getWeight() + divide.getWeight());
                    hashMap.put(divide.getDate().toString(), todayDivide1);
                } else {
                    hashMap.put(divide.getDate().toString(), todayDivide);
                }
                //todayDivides.add(todayDivide);

                //统计总数
                if (divide.getDivideType() == 0) {
                    everyDayDivide.setTotalQuantity(everyDayDivide.getTotalQuantity() + divide.getQuantity());
                    everyDayDivide.setTotalWeight(everyDayDivide.getTotalWeight() + divide.getWeight());
                } else {
                    everyDayDivide.setTotalQuantity(everyDayDivide.getTotalQuantity() - divide.getQuantity());
                    everyDayDivide.setTotalWeight(everyDayDivide.getTotalWeight() - divide.getWeight());
                }
                //everyDayDivide.setDataList(todayDivides);
            }
            everyDayDivide.setDataMap(hashMap);
            list.add(everyDayDivide);
        }
        return list;
    }


    @Override
    public List<RespSiteDivide> selectSiteDivide(List<String> siteNos, Date startDate, Date endDate) {
        //如果为空查所有场
        if (siteNos == null || siteNos.size() == 0) {
            siteNos = siteService.getAllSiteNo();
        }
        //查询每个场的分塘记录
        LinkedList<RespSiteDivide> list = new LinkedList<>();

        //遍历每个场
        for (String siteNo : siteNos) {
            //初始化
            RespSiteDivide respSiteDivide = this.initRespSiteDivide(siteNo);
            respSiteDivide.setKey(siteNo+"-new");
            respSiteDivide.setType(1);
            RespSiteDivide respSiteDivideOld = this.initRespSiteDivide(siteNo);
            respSiteDivideOld.setKey(siteNo+"-old");
            respSiteDivideOld.setType(2);
            this.initDataMap(respSiteDivide,startDate,endDate);
            this.initDataMap(respSiteDivideOld,startDate,endDate);
            list.add(respSiteDivide);
            list.add(respSiteDivideOld);
            //查询该场所有的塘
            List<String> poolNos = curPoolService.getPoolsBySiteNo(siteNo);
            if (poolNos == null || poolNos.size() == 0) {
                continue;
            }
            //查询该场的分塘记录
            QueryWrapper<Divide> wrapper = new QueryWrapper<>();
            wrapper.in("pool_no", poolNos);
            wrapper.between("date", startDate, endDate);
            List<Divide> divideList = this.list(wrapper);
            //遍历每条分塘记录
            for (Divide divide : divideList) {
                if (divide.getType() == 1){
                    HashMap<String, SiteDivide> dataMap = respSiteDivide.getDataMap();
                    SiteDivide siteDivide = dataMap.get(divide.getDate().toString());
                    //如果是分进
                    if (divide.getDivideType() == 0) {
                        siteDivide.setQuantity(siteDivide.getQuantity() + divide.getQuantity());
                        siteDivide.setWeight(siteDivide.getWeight() + divide.getWeight());
                        dataMap.put(divide.getDate().toString(), siteDivide);
                        respSiteDivide.setTotalQuantity(respSiteDivide.getTotalQuantity() + divide.getQuantity());
                        respSiteDivide.setTotalWeight(respSiteDivide.getTotalWeight() + divide.getWeight());
                    }else {
                        siteDivide.setQuantity(siteDivide.getQuantity() - divide.getQuantity());
                        siteDivide.setWeight(siteDivide.getWeight() - divide.getWeight());
                        dataMap.put(divide.getDate().toString(), siteDivide);
                        respSiteDivide.setTotalQuantity(respSiteDivide.getTotalQuantity() - divide.getQuantity());
                        respSiteDivide.setTotalWeight(respSiteDivide.getTotalWeight() - divide.getWeight());
                    }
                }
                else if (divide.getType() == 2){
                    HashMap<String, SiteDivide> dataMap = respSiteDivideOld.getDataMap();
                    SiteDivide siteDivide = dataMap.get(divide.getDate().toString());
                    //如果是分进
                    if (divide.getDivideType() == 0) {
                        siteDivide.setQuantity(siteDivide.getQuantity() + divide.getQuantity());
                        siteDivide.setWeight(siteDivide.getWeight() + divide.getWeight());
                        dataMap.put(divide.getDate().toString(), siteDivide);
                        respSiteDivideOld.setTotalQuantity(respSiteDivideOld.getTotalQuantity() + divide.getQuantity());
                        respSiteDivideOld.setTotalWeight(respSiteDivideOld.getTotalWeight() + divide.getWeight());
                    }else {
                        siteDivide.setQuantity(siteDivide.getQuantity() - divide.getQuantity());
                        siteDivide.setWeight(siteDivide.getWeight() - divide.getWeight());
                        dataMap.put(divide.getDate().toString(), siteDivide);
                        respSiteDivideOld.setTotalQuantity(respSiteDivideOld.getTotalQuantity() - divide.getQuantity());
                        respSiteDivideOld.setTotalWeight(respSiteDivideOld.getTotalWeight() - divide.getWeight());
                    }
                }

            }
        }


        return list;
    }

    @Override
    public List<DivideRecord> selectDivideRecord(List<String> poolNos, Date startDate, Date endDate, String userId) {
        if (poolNos == null || poolNos.size() == 0) {
            poolNos = curPoolService.getPoolNos();
        }

        QueryWrapper<Divide> wrapper = new QueryWrapper<>();
        wrapper.in("pool_no", poolNos);
        wrapper.between("date", startDate, endDate);
        wrapper.eq("divide_type", 1);
        if (userId != null && !userId.equals("")){
            wrapper.eq("user_id", userId);
        }
        List<Divide> list = this.list(wrapper);

        LinkedList<DivideRecord> divideRecords = new LinkedList<>();
        HashMap<String, String> allUser = userService.getAllUser();

        for (Divide divide : list) {
            DivideRecord divideRecord = new DivideRecord();
            ReportBasic reportBasic = new ReportBasic();
            reportBasic.setPoolNo(divide.getPoolNo());
            String s = allUser.get(divide.getUserId());
            reportBasic.setReporter(s);
            reportBasic.setDate(divide.getDate());
            reportBasic.setReportDate(divide.getReportDate());
            divideRecord.setPoolNoOut(divide.getPoolNo());
            divideRecord.setPoolNoIn(divide.getComeFrom());
            divideRecord.setQuantity(divide.getQuantity());
            divideRecord.setWeight(divide.getWeight());
            divideRecord.setReportBasic(reportBasic);
            divideRecords.add(divideRecord);
        }
        return divideRecords;
    }


    //初始化场查询的分塘记录
    private RespSiteDivide initRespSiteDivide(String siteNo) {
        RespSiteDivide respSiteDivide = new RespSiteDivide();
        respSiteDivide.setSiteNo(siteNo);
        Site site = siteService.getSiteByNo(siteNo);
        respSiteDivide.setArea(site.getArea());
        respSiteDivide.setKey(siteNo);
        HashMap<String, SiteDivide> dataMap = new HashMap<>();
        respSiteDivide.setDataMap(dataMap);
        respSiteDivide.setTotalQuantity(0);
        respSiteDivide.setTotalWeight(0.0);
        return respSiteDivide;
    }


    private void initDataMap(RespSiteDivide respSiteDivide,Date startTime, Date endTime){
        Date tmpDate = new Date(startTime.getTime());
        HashMap<String, SiteDivide> dataMap = respSiteDivide.getDataMap();
        //初始化dataMap
        while (tmpDate.getTime() <= endTime.getTime()){
            SiteDivide siteDivide = new SiteDivide();
            siteDivide.setSiteNo(respSiteDivide.getSiteNo());
            siteDivide.setDate(new Date(tmpDate.getTime()));
            siteDivide.setQuantity(0);
            siteDivide.setWeight(0.0);
            dataMap.put(tmpDate.toString(),siteDivide);
            tmpDate.setTime(tmpDate.getTime()+24*60*60*1000);
        }
    }



}
